﻿#include "codecs/external_video_encoder_factory.h"

#include <absl/strings/match.h>
#include <rtc_base/logging.h>
#include <modules/video_coding/codecs/vp8/include/vp8.h>
#include <modules/video_coding/codecs/vp9/include/vp9.h>
#include <modules/video_coding/codecs/h264/include/h264.h>

#include "codecs/h264_encoder_impl.h"

namespace xrtc {

namespace {

std::vector<webrtc::SdpVideoFormat>
SupportedH264Codecs() {
    return {
        webrtc::CreateH264Format(webrtc::H264Profile::kProfileBaseline,
            webrtc::H264Level::kLevel3_1, "1"),
        webrtc::CreateH264Format(webrtc::H264Profile::kProfileBaseline,
            webrtc::H264Level::kLevel3_1, "0"),
        webrtc::CreateH264Format(webrtc::H264Profile::kProfileConstrainedBaseline,
            webrtc::H264Level::kLevel3_1, "1"),
        webrtc::CreateH264Format(webrtc::H264Profile::kProfileConstrainedBaseline,
            webrtc::H264Level::kLevel3_1, "0")
    };
}

} // namespace

std::vector<webrtc::SdpVideoFormat> 
ExternalVideoEncoderFactory::GetSupportedFormats() const {
    std::vector<webrtc::SdpVideoFormat> supported_formats;

    // 支持VP8
    supported_formats.push_back(
        webrtc::SdpVideoFormat(cricket::kVp8CodecName));

    // 支持VP9
    for (const webrtc::SdpVideoFormat& format : webrtc::SupportedVP9Codecs()) {
        supported_formats.push_back(format);
    }

    // 支持H264
    for (const webrtc::SdpVideoFormat& format : SupportedH264Codecs()) {
        supported_formats.push_back(format);
    }

    return supported_formats;
}

std::unique_ptr<webrtc::VideoEncoder> 
ExternalVideoEncoderFactory::CreateVideoEncoder(
    const webrtc::SdpVideoFormat& format) 
{
    if (absl::EqualsIgnoreCase(format.name, cricket::kVp8CodecName)) {
        return webrtc::VP8Encoder::Create();
    }

    if (absl::EqualsIgnoreCase(format.name, cricket::kVp9CodecName)) {
        return webrtc::VP9Encoder::Create(cricket::VideoCodec(format));
    }

    if (absl::EqualsIgnoreCase(format.name, cricket::kH264CodecName)) {
        return std::make_unique<H264EncoderImpl>(cricket::VideoCodec(format));
    }

    RTC_LOG(LS_WARNING) << "create video encoder failed, format not supported,"
        << "format: " << format.name;

    return nullptr;
}

std::unique_ptr<ExternalVideoEncoderFactory> 
CreateExternalVideoEncoderFactory() {
    return std::make_unique<ExternalVideoEncoderFactory>();
}

} // namespace xrtc